home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / c / allocaap.zip / ALLOCA.DOC < prev    next >
Text File  |  1990-08-29  |  5KB  |  124 lines

  1. alloca() by Alexander Pruss for Turbo C
  2. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  3.  
  4. email: pruss@uwo.ca  // internet
  5.        pruss@uwovax  // bitnet
  6.        pruss@ria     // uucp
  7.  
  8. Released into the public domain with the restriction that the acknowledgements
  9. to Alexander Pruss are preserved.
  10.  
  11.  
  12. Warranty: NONE!  This has undergone considerable testing, but it is likely
  13.           not to work in many cases.  It may cause damage to your system if
  14.           it fails in a particularly nasty way.  USE AT YOUR OWN RISK!
  15.  
  16.  
  17. A few words about stack frames.
  18. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  19. alloca() needs a real stack frame in the function that calls it.
  20. This means that the function must begin with an ENTER (or push bp; mov bp,sp)
  21. and end with a LEAVE (or mov sp,bp; pop bp).  Just setting the compiler -k
  22. (standard frame) switch is not enough as the LEAVE is then changed into a
  23. straight pop bp.
  24.  
  25. The correct stack frame will be inserted provided the compiler cannot
  26. make all the local variables into registers.  Thus if the calling function
  27. has more than two integer auto variables or it has a noninteger and nonfloat
  28. auto variable (a near pointer we consider an integer, but not a far pointer)
  29. then it will have a stack frame.
  30.  
  31. I.e. the functions below have a stack frame:
  32. f(a)  { int x; int y; int z; ... }  /* 3 integer vars */
  33. g(a)  { char x; ... }               /* noninteger var */
  34. h(a)  { char far *x; ... }          /* far pointer    */
  35. i(a)  { { char dummy; dummy=dummy; } }  /* more about this later on */
  36.  
  37. and the functions below may or may not have a proper stack frame:
  38. F(a)  { int x; int y; ... }
  39. G(a)  { int x; ... }
  40. H(a)  { char near *x; int y; ... }
  41. I(a)  { float x; double y; ... }    /* floats might go on 8087 stack */
  42.  
  43. You can force a stack frame by inserting somewhere in the function, where
  44. the flow of execution will reach it, the line:
  45.   { char dummy; dummy=dummy; }
  46.  
  47.  
  48. How to use alloca().
  49. ~~~~~~~~~~~~~~~~~~~~
  50. #include "alloca.h"
  51.  
  52. now you can use alloca() as:
  53.         void *alloca(unsigned size);
  54.  
  55. alloca() is a replacement for malloc() which allocates space which will
  56. be deallocated upon return from the calling routine.
  57.  
  58. You must link in the appropriate version unless you are using INLINE_ALLOCA
  59. (see below):
  60.  
  61. memory model      object file
  62. ~~~~~~~~~~~~      ~~~~~~~~~~~
  63. tiny, small       alloca.obs
  64. medium            alloca.obm
  65. compact           alloca.obc
  66. large, huge       alloca.obl
  67.  
  68. Options:
  69.  If you insert #define INLINE_ALLOCA before #include'ing alloca.h, then you
  70.  will have a much faster (but larger) inline version.  You need no longer
  71.  link in the object file.
  72.  
  73.  If you insert #define FORCE_STACK, then a stack frame is forced onto the
  74.  function automatically.  This is done as alloca() is defined to be
  75.  alloca(); { char dummy; dummy=dummy; }
  76.  This means, however, that lexically all calls to alloca() must be of the
  77.  following form:
  78.   xxx alloca(yyy);
  79.  where xxx and yyy are arbitrary things (conforming to C syntax).  Thus,
  80.   x = 3+(char *)alloca(y); is allowed, while
  81.   x = (char *)alloca(y) + 3; is illegal.  (And will likely produce a
  82.  compiler error.)
  83.  
  84. Compiler
  85. ~~~~~~~~
  86. Tested under Turbo C 2.0.
  87.  
  88. Bugs
  89. ~~~~
  90. If the alloca()'d pointer is assigned to z and z is unitialized, the compiler
  91. may generate a `possible use before definition' error for z.  Ignore this
  92. error.  I have yet to find out what causes it, but the assembly output is
  93. O.K. even if the error occurs.
  94.  
  95. The function must have a proper stack frame.  (See above).
  96.  
  97. alloca() in FORCE_STACK mode must be called lexically as xxx alloca(yyy);
  98. (see above)
  99.  
  100. alloca() will not work in a long and complicated expression or in the middle
  101. of a function call as at that time the stack may be screwed up.  It is safe
  102. to use alloca() as the last argument to a function call, so:
  103.  z=f(alpha,alloca(100)); is O.K. (unless in FORCE_STACK mode), while:
  104.  z=F(alloca(100),alpha); is illegal and will likely crash.  (compiler error
  105. is generated in FORCE_STACK mode).
  106. Long arithmetic expressions may save intermediate results on the stack.  This
  107. will cause alloca() to screw up, so do not do more than a few simple operations
  108. on the return value.  You should use alloca() mainly as z=alloca(y); which will
  109. work unless y is a long and complex expression.
  110. In FORCE_STACK mode some long arithmetic expressions may generate compiler errors
  111. but normally if alloca() screws up the compiling will be O.K., just the
  112. program will crash.
  113.  
  114. Stack overflow is not checked, so alloca() will always work.
  115.  
  116. I haven't time to test as thoroughly as I wish to.
  117.  
  118. News!
  119. ~~~~~
  120. I got it to work with TC++ 1.00.  I had to change the FORCE_STACK method.
  121. Chars can now be made into register variables, so g() and i() defined above
  122. in the stack frame section do not have stack frames.  Now the stack is forced
  123. by using a long.  See alloca.h for more information.
  124.